/**
 * @file Image.h
 * @brief Fichier d'entête du module Image.
 *
 * 
 */
#ifndef H_IMAGE_H
#define H_Image_H

/* ********************************************************************* */
/*                                                                       */
/*                        Librairies de l'image                          */
/*                                                                       */
/* ********************************************************************* */

#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include "Pixel.h"

/* ********************************************************************* */
/*                                                                       */
/*                        Définitions de types                           */
/*                                                                       */
/* ********************************************************************* */

/**
 * @struct sImage
 * @brief Structure utilisée pour la gestion d'une image.
 *
 * Cette structure est utilisée pour gérer une image.
 Les champs de cette structures doivent être modifiés ou lus
 par les accesseurs et mutateurs.
 */

struct sImage {

    Pixel *pix; /** Données de l'image */
    int dimx;   /** Dimension en X de l'image */
    int dimy;   /** Dimension en y de l'image */

} ;

/**
 * @typedef Image
 * @brief Redéfinit la structure sImage.
 */
typedef struct sImage Image ;



/* ********************************************************************* */
/*                                                                       */
/*                 Fonctions relatives aux images                        */
/*                                                                       */
/* ********************************************************************* */

/**
 * @fn void imInit ( Image *im, const int dimx, const int dimy) ;
 * @brief Initialise une image.
 *
 * @param[in, out] im Pointeur vers l'image à initialiser.
 * @param[in] dimx Largeur de l'image.
 * @param[in] dimy Hauteur de l'image.
 * @return 0 si tout est OK
 */
void imInit ( Image *im, const int dimx, const int dimy) ;

/**
 * @fn void imLibere (Image *im)
 * @brief Libère une image de la mémoire.
 *
 * @param[in, out] im Pointeur vers l'image à libérer.
 * @return 0 si tout est OK
 */
void imLibere (Image *im) ;

/**
 * @fn Image* imCreer(const int dimx, const int dimy)
 * @brief Alloue dans le tas une structure Image puis l'initialise avec imInit.
 *
 * @param[in] dimx Largeur de l'image.
 * @param[in] dimy Hauteur de l'image.
 * @return Un pointeur sur Image.
 */
Image * imCreer(const int dimx, const int dimy) ;

/**
 * @fn void imDetruire(Image *im)
 * @brief Libere le tableau de pixel en appelant imLibere puis détruit la structure image.
 *
 * @param[in, out] im Pointeur vers l'image à detruir.
 * @return 0 si tout est OK
 */
void imDetruire(Image *im) ;

/* ********************************************************************* */
/*                                                                       */
/*           Accesseurs et Mutateurs de la structure Image               */
/*                                                                       */
/* ********************************************************************* */

/**
 * @fn Pixel getPix(const Image *im, const int x, const int y)
 * @brief Récupère le pixel de coordonnée (x,y) en vérifiant leur validité.
 *
 * @param[in, out] im Pointeur vers l'image.
 * @param[in] x coordonnée x du pixel à Récupèrer.
 * @param[in] y coordonnée y du pixel à Récupèrer.
 * @return la valeur du pixel demandé.
 */
Pixel getPix(const Image *im, const int x, const int y) ;


/**
 * @fn void setPix(Image *im, const int x, const int y,const Pixel *couleur)
 * @brief Modifie le pixel de coordonnée (x,y).
 *
 * @param[in, out] im Pointeur vers l'image.
 * @param[in] x coordonnée x du pixel à modifier.
 * @param[in] y coordonnée y du pixel à modifier.
 * @param[in] couleur pointeur sur Nouvel couleur du pixel selectioné.
 * @return 0 si tout est OK.
 */
void setPix(Image *im, const int x, const int y,const Pixel * couleur) ;


/* ********************************************************************* */
/*                                                                       */
/*                 Fonctions relatives aux rectangles                    */
/*                                                                       */
/* ********************************************************************* */

/**
 * @fn void imDessineRectangle(Image *im, const int Xmin, const int Ymin, const int Xmax, const int Ymax,const Pixel * couleur)
 * @brief Dessine un rectangle de couleur dans l'image en utilisant setPix.
 *
 * @param[in, out] im Pointeur vers l'image.
 * @param[in] Xmin Largeur minimum du rectangle.
 * @param[in] Ymin Hauteur minimum du rectangle.
 * @param[in] Xmax Largeur maximum du rectangle.
 * @param[in] Ymax Hauteur maximum du rectangle.
 * @param[in] couleur pointeur sur Couleur du rectangle.
 * @return 0 si tout est OK.
 */
void imDessineRectangle(Image *im, const int Xmin, const int Ymin, const int Xmax, const int Ymax,const Pixel * couleur) ;


/**
 * @fn void imEffacer(Image *im, const Pixel * couleur)
 * @brief Efface l'image en appelant imDessineRectangle avec le bon rectangle.
 *
 * @param[in, out] im Pointeur vers l'image.
 * @param[in] couleur pointeur sur Couleur de suppression.
 * @return 0 si tout est OK.
 */
void imEffacer(Image *im, const Pixel * couleur) ;

/* ********************************************************************* */
/*                                                                       */
/*             Fonctions relatives aux gestiond'images                   */
/*                                                                       */
/* ********************************************************************* */

/**
 * @fn void imSauver(const Image *pIm, const char filename[])
 * @brief sauvegarde une image au format .ppm.
 *
 * @param[in, out] pIm Pointeur vers l'image.
 * @param[in] filename fichier à sauver.
 * @return 0 si tout est OK.
 */
void imSauver(const Image *pIm, const char filename[]) ;

/**
 * @fn void imOuvrir(Image *pIm, const char filename[])
 * @brief Ouvre une image au format .ppm.
 *
 * @param[in, out] pIm Pointeur vers l'image.
 * @param[in] filename fichier à ouvrir au format .ppm.
 * @return 0 si tout est OK.
 */
void imOuvrir(Image *pIm, const char filename[]) ;

/**
 * @fn void imPrintf(const Image *pIm)
 * @brief sauvegarde une image au format .ppm.
 *
 * @param[in, out] pIm Pointeur vers l'image à imprimer.
 * @return 0 si tout est OK.
 */
void imPrintf(const Image *pIm) ;



/* ********************************************************************* */
/*                                                                       */
/*                           Test de regression                          */
/*                                                                       */
/* ********************************************************************* */

/**
 * @fn void ImRegressionTest(void)
 * @brief Teste toutes les fonctions du module image.h
 *
 * @return 0 si tout est OK
 */
void ImRegressionTest(void) ;

#endif
